import { remote } from '@/api/admin/dict'

/**
 * 字典 map
 * @type {Record<string,Array<DictItem>>}
 */
const dictCache = {}
/**
 * 字典 map
 * @type {Record<string,Record<string,any>>}
 */
const dictCacheMap = {}
/**
 * 请求缓存
 * @type {Record<string,Promise<Array<DictItem>>>}
 */
const promiseCache = {}

/**
 * 获取字典
 * @param type 字典类型
 * @param cache 是否使用缓存
 * @return {Promise<Array<DictItem>>}
 */
export const getDictData = async (type, cache = true) => {
  const dict = dictCache[type]
  if (cache && dict) {
    return dict
  } else {
    return fetchDictData(type, cache)
  }
}

/**
 *
 * @param type
 * @param cache
 * @returns {Promise<Array<DictItem>>}
 */
const fetchDictData = (type, cache = true) => {
  if (promiseCache[type]) {
    return promiseCache[type]
  }
  const promise = new Promise((resolve, reject) => {
    if (cache && dictCache[type]) {
      resolve(dictCache[type])
    } else {
      remote(type)
        .then(res => {
          let items = res.data.data
          if (cache) {
            const map = {}
            items.forEach(({ label, value }) => {
              map[value] = Object.freeze({ label, value })
            })
            dictCacheMap[type] = map
            items = Object.freeze(items)
            dictCache[type] = items
          }
          promiseCache[type] = null
          resolve(items)
        })
        .catch(e => {
          promiseCache[type] = null
          reject(e)
        })
    }
  })
  promiseCache[type] = promise
  return promise
}

/**
 * 获取字典项
 * @param type
 * @param value
 * @param cache
 * @return {Promise<DictItem>}
 */
export const getDictItem = async (type, value, cache = true) => {
  const cached = dictCacheMap[type]
  let item
  if (cache && cached) {
    item = cached[value]
  } else {
    const items = await getDictData(type, cache)
    if (cache) {
      item = dictCacheMap[type][value]
    } else {
      for (let i = 0; i < items.length; i++) {
        const temp = items[i]
        if (temp.value === value) {
          item = temp
          break
        }
      }
    }
  }

  return item
}

/**
 * 获取字典项
 * @param type
 * @param value
 * @param cache
 * @return {Promise<string|any>}
 */
export const getDictLabel = async (type, value, cache = true) => (await getDictItem(type, value, cache))?.label || value || ''
